// parking_network.c
#include <stdio.h>            // 标准输入输出函数
#include <stdlib.h>           // 标准库函数（内存分配、进程控制等）
#include <string.h>           // 字符串处理函数
#include <unistd.h>           // Unix标准函数（文件操作、进程控制等）
#include <pthread.h>          // 线程库函数
#include <sys/socket.h>       // 套接字编程接口
#include <netinet/in.h>       // Internet地址族定义
#include <arpa/inet.h>        // IP地址转换函数
#include <errno.h>            // 错误号定义
#include "cJSON.h"            // JSON解析库
#include "parking_network.h"  // 网络模块头文件
#include "parking_hardware.h" // 硬件控制头文件

// 保持原有的全局变量定义
volatile int running = 1;                                      // 程序运行标志，volatile确保多线程可见性
int socket_fd        = -1;                                     // 套接字文件描述符，-1表示未连接
parking_data_t parking_data;                                   // 停车场数据结构体
static pthread_t tcp_thread;                                   // TCP客户端线程ID
static pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER; // 数据互斥锁，保护共享数据

// 添加异步回调函数
void async_ui_update(void * param)
{
    parking_data_t * data = (parking_data_t *)param; // 将参数转换为停车场数据指针
    update_ui_with_data(data);                       // 调用UI更新函数
    free(data);                                      // 释放动态分配的内存，防止内存泄漏
}

// 原有的connect_to_server函数，只做重命名
int network_connect_to_server(void)
{
    struct sockaddr_in server_addr; // 服务器地址结构体

    // 创建TCP套接字，AF_INET=IPv4，SOCK_STREAM=TCP，0=默认协议
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_fd < 0) {                   // 套接字创建失败
        perror("socket creation failed"); // 打印错误信息
        return -1;                        // 返回错误码
    }

    int opt = 1; // 套接字选项值
    // 设置套接字选项：允许地址重用，避免"Address already in use"错误
    setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // 配置服务器地址
    server_addr.sin_family      = AF_INET;              // IPv4地址族
    server_addr.sin_port        = htons(SERVER_PORT);   // 端口号，htons转换字节序
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // IP地址，inet_addr转换字符串为网络字节序

    // 连接到服务器
    if(connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("connect to server failed"); // 连接失败
        close(socket_fd);                   // 关闭套接字
        socket_fd = -1;                     // 重置套接字描述符
        return -1;                          // 返回错误码
    }

    printf("Connected to server [%s:%d]\n", SERVER_IP, SERVER_PORT); // 连接成功提示
    return 0;                                                        // 返回成功
}

// 原有的send_command_response函数
// json格式示例
// {
//     "type": "command_response",
//     "request_id": "req_123456",
//     "status": "success",
//     "message": "LED turned ON",
//     "timestamp": 1640995200
// }
void network_send_command_response(const char * request_id, const char * status, const char * message)
{
    if(socket_fd < 0) { // 检查套接字是否有效
        printf("WARNING: Cannot send response, socket not connected\n");
        return; // 套接字无效，直接返回
    }

    // 创建JSON响应对象
    cJSON * response = cJSON_CreateObject();
    cJSON_AddStringToObject(response, "type", "command_response"); // 响应类型
    cJSON_AddStringToObject(response, "request_id", request_id);   // 请求ID
    cJSON_AddStringToObject(response, "status", status);           // 状态（success/error）
    cJSON_AddStringToObject(response, "message", message);         // 消息内容
    cJSON_AddNumberToObject(response, "timestamp", time(NULL));    // 时间戳

    // 将JSON对象转换为字符串（无格式化的紧凑格式）
    char * response_str = cJSON_PrintUnformatted(response);
    printf("Sending response: %s\n", response_str); // 打印发送的响应

    // 发送响应数据到服务器
    ssize_t ret = send(socket_fd, response_str, strlen(response_str), 0);
    if(ret <= 0) { // 发送失败
        printf("ERROR: Failed to send command response\n");
    }

    cJSON_Delete(response); // 释放JSON对象内存
    free(response_str);     // 释放JSON字符串内存
}

// 原有的receive_thread函数
void * network_receive_thread(void * arg)
{
    char buffer[BUFFER_SIZE]; // 接收缓冲区
    ssize_t bytes_read;       // 实际读取的字节数

    while(running) {         // 主循环，running为1时持续运行
        if(socket_fd >= 0) { // 检查套接字是否有效
            // 从套接字接收数据，非阻塞模式
            bytes_read = recv(socket_fd, buffer, BUFFER_SIZE - 1, 0);
            if(bytes_read > 0) {           // 成功接收到数据
                buffer[bytes_read] = '\0'; // 在缓冲区末尾添加字符串结束符
                printf("=== RAW DATA RECEIVED ===\n");
                printf("Received %zd bytes: %s\n", bytes_read, buffer);

                // 检查接收的数据是否为命令（包含"command_name"字段）
                if(strstr(buffer, "command_name") != NULL) {
                    printf("Detected command, calling handle_server_command\n");
                    network_handle_server_command(buffer); // 处理服务器命令
                } else {
                    printf("Not a command, skipping\n"); // 非命令数据，跳过
                }

                printf("=== DATA PROCESSING COMPLETE ===\n");
            } else if(bytes_read == 0) { // 服务器断开连接
                printf("Server disconnected\n");
                close(socket_fd);      // 关闭套接字
                socket_fd = -1;        // 重置套接字描述符
            } else {                   // 接收出错
                perror("recv failed"); // 打印错误信息
                usleep(100000);        // 休眠100ms避免CPU占用过高
            }
        } else {            // 套接字无效
            usleep(100000); // 休眠100ms等待重连
        }
    }

    printf("Receive thread exiting\n"); // 线程退出提示
    return NULL;                        // 线程返回值
}

// 原有的serialize_parking_data函数
// 生成的jcon结构:
// {
//     "device_id": "gec6818_parking_001",
//     "timestamp": 1640995200,
//     "total_spaces": 500,
//     "available_spaces": 325,
//     "occupied_spaces": 175,
//     "utilization_rate": 35,
//     "temperature": 25,
//     "humidity": 60,
//     "light_level": 450,
//     "air_quality": 75,
//     "vehicles_in": 1245,
//     "vehicles_out": 1198,
//     "vehicles_current": 47,
//     "peak_hour_flag": 0,
//     "floor_b1_total": 200,
//     "floor_b1_available": 50,
//     "floor_b1_utilization": 75,
//     "floor_b2_total": 150,
//     "floor_b2_available": 60,
//     "floor_b2_utilization": 60,
//     "floor_b3_total": 150,
//     "floor_b3_available": 22,
//     "floor_b3_utilization": 85,
//     "avg_parking_time_x100": 250,
//     "avg_consumption_x100": 4560,
//     "member_ratio": 68,
//     "parking_time_less_1h": 35,
//     "parking_time_1_2h": 20,
//     "parking_time_2_4h": 20,
//     "parking_time_more_4h": 25,
//     "recognized_vehicles": 1245,
//     "unrecognized_rate_x100": 230,
//     "vehicle_type_truck": 560,
//     "vehicle_type_suv": 374,
//     "vehicle_type_car": 311,
//     "common_feedback": "车位不足",
//     "avg_waiting_time_x100": 850,
//     "facility_score_x100": 450,
//     "service_score_x100": 430,
//     "satisfaction_score": 90,
//     "hour_6_count": 20,
//     "hour_8_count": 120,
//     "hour_10_count": 80,
//     "hour_12_count": 40,
//     "hour_14_count": 60,
//     "hour_16_count": 100,
//     "hour_18_count": 130,
//     "hour_20_count": 70,
//     "status": "normal"
// }
char * network_serialize_parking_data(const parking_data_t * data)
{
    static char json_buffer[4096];       // 静态JSON缓冲区，避免重复分配内存
    char * ptr    = json_buffer;         // 缓冲区当前位置指针
    int remaining = sizeof(json_buffer); // 剩余缓冲区大小
    int written;                         // 每次写入的字节数

    // 完整的JSON构建逻辑
    written = snprintf(ptr, remaining, "{"); // 开始JSON对象
    if(written > 0 && written < remaining) { // 写入成功且有剩余空间
        ptr += written;                      // 移动指针
        remaining -= written;                // 减少剩余空间
    }

    // 设备ID和时间戳
    written = snprintf(ptr, remaining,
                       "\"device_id\":\"gec6818_parking_001\"," // 设备标识符
                       "\"timestamp\":%" PRId64 ",",            // 时间戳，PRId64确保跨平台兼容
                       data->timestamp);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 基础停车数据
    written = snprintf(ptr, remaining,
                       "\"total_spaces\":%" PRId32 ","      // 总车位数
                       "\"available_spaces\":%" PRId32 ","  // 可用车位数
                       "\"occupied_spaces\":%" PRId32 ","   // 已用车位数
                       "\"utilization_rate\":%" PRId32 ",", // 利用率百分比
                       data->total_spaces, data->available_spaces, data->occupied_spaces, data->utilization_rate);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 环境数据
    written = snprintf(ptr, remaining,
                       "\"temperature\":%" PRId32 ","  // 温度
                       "\"humidity\":%" PRId32 ","     // 湿度
                       "\"light_level\":%" PRId32 ","  // 光照强度
                       "\"air_quality\":%" PRId32 ",", // 空气质量
                       data->temperature, data->humidity, data->light_level, data->air_quality);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 进出统计
    written = snprintf(ptr, remaining,
                       "\"vehicles_in\":%" PRId32 ","      // 今日进场车辆数
                       "\"vehicles_out\":%" PRId32 ","     // 今日出场车辆数
                       "\"vehicles_current\":%" PRId32 "," // 当前在场车辆数
                       "\"peak_hour_flag\":%" PRId32 ",",  // 高峰时段标志
                       data->vehicles_in, data->vehicles_out, data->vehicles_current, data->peak_hour_flag);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 楼层数据
    written = snprintf(ptr, remaining,
                       "\"floor_b1_total\":%" PRId32 ","        // 地下1层总车位
                       "\"floor_b1_available\":%" PRId32 ","    // 地下1层可用车位
                       "\"floor_b1_utilization\":%" PRId32 ","  // 地下1层利用率
                       "\"floor_b2_total\":%" PRId32 ","        // 地下2层总车位
                       "\"floor_b2_available\":%" PRId32 ","    // 地下2层可用车位
                       "\"floor_b2_utilization\":%" PRId32 ","  // 地下2层利用率
                       "\"floor_b3_total\":%" PRId32 ","        // 地下3层总车位
                       "\"floor_b3_available\":%" PRId32 ","    // 地下3层可用车位
                       "\"floor_b3_utilization\":%" PRId32 ",", // 地下3层利用率
                       data->floor_b1_total, data->floor_b1_available, data->floor_b1_utilization, data->floor_b2_total,
                       data->floor_b2_available, data->floor_b2_utilization, data->floor_b3_total,
                       data->floor_b3_available, data->floor_b3_utilization);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 客户行为分析
    written = snprintf(ptr, remaining,
                       "\"avg_parking_time_x100\":%" PRId32 "," // 平均停车时间（x100倍）
                       "\"avg_consumption_x100\":%" PRId32 ","  // 平均消费金额（x100倍）
                       "\"member_ratio\":%" PRId32 ",",         // 会员比例
                       data->avg_parking_time_x100, data->avg_consumption_x100, data->member_ratio);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 停车时长分布
    written = snprintf(ptr, remaining,
                       "\"parking_time_less_1h\":%" PRId32 ","  // 停车<1小时
                       "\"parking_time_1_2h\":%" PRId32 ","     // 停车1-2小时
                       "\"parking_time_2_4h\":%" PRId32 ","     // 停车2-4小时
                       "\"parking_time_more_4h\":%" PRId32 ",", // 停车>4小时
                       data->parking_time_less_1h, data->parking_time_1_2h, data->parking_time_2_4h,
                       data->parking_time_more_4h);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 车牌识别数据
    written = snprintf(ptr, remaining,
                       "\"recognized_vehicles\":%" PRId32 ","    // 已识别车辆数
                       "\"unrecognized_rate_x100\":%" PRId32 "," // 未识别率（x100倍）
                       "\"vehicle_type_truck\":%" PRId32 ","     // 货车数量
                       "\"vehicle_type_suv\":%" PRId32 ","       // SUV数量
                       "\"vehicle_type_car\":%" PRId32 ",",      // 轿车数量
                       data->recognized_vehicles, data->unrecognized_rate_x100, data->vehicle_type_truck,
                       data->vehicle_type_suv, data->vehicle_type_car);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 客户反馈数据
    written = snprintf(ptr, remaining,
                       "\"common_feedback\":\"%s\","            // 常见反馈内容
                       "\"avg_waiting_time_x100\":%" PRId32 "," // 平均等待时间（x100倍）
                       "\"facility_score_x100\":%" PRId32 ","   // 设施评分（x100倍）
                       "\"service_score_x100\":%" PRId32 ","    // 服务评分（x100倍）
                       "\"satisfaction_score\":%" PRId32 ",",   // 满意度评分
                       data->common_feedback, data->avg_waiting_time_x100, data->facility_score_x100,
                       data->service_score_x100, data->satisfaction_score);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 高峰时段数据
    written = snprintf(ptr, remaining,
                       "\"hour_6_count\":%" PRId32 ","   // 6点车流量
                       "\"hour_8_count\":%" PRId32 ","   // 8点车流量
                       "\"hour_10_count\":%" PRId32 ","  // 10点车流量
                       "\"hour_12_count\":%" PRId32 ","  // 12点车流量
                       "\"hour_14_count\":%" PRId32 ","  // 14点车流量
                       "\"hour_16_count\":%" PRId32 ","  // 16点车流量
                       "\"hour_18_count\":%" PRId32 ","  // 18点车流量
                       "\"hour_20_count\":%" PRId32 ",", // 20点车流量
                       data->hour_6_count, data->hour_8_count, data->hour_10_count, data->hour_12_count,
                       data->hour_14_count, data->hour_16_count, data->hour_18_count, data->hour_20_count);
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    // 状态字段并结束JSON对象
    written = snprintf(ptr, remaining, "\"status\":\"normal\"}"); // 设备状态
    if(written > 0 && written < remaining) {
        ptr += written;
        remaining -= written;
    }

    printf("DEBUG: Serialized data length: %zu\n", strlen(json_buffer)); // 调试信息
    return json_buffer;                                                  // 返回JSON字符串
}

// 原有的tcp_client_thread函数
void * network_tcp_client_thread(void * arg)
{
    int ret;                  // 返回值变量
    parking_data_t send_data; // 要发送的数据
    pthread_t recv_thread;    // 接收线程ID

    printf("TCP Client Thread Starting...\n");

    // 初始化默认数据
    initialize_default_data();

    // 连接到服务器
    if(network_connect_to_server() != 0) {
        printf("Initial connection failed, will retry...\n"); // 初始连接失败
    }

    // 创建数据接收线程
    if(pthread_create(&recv_thread, NULL, network_receive_thread, NULL) != 0) {
        printf("Failed to create receive thread\n"); // 线程创建失败
        return NULL;                                 // 返回错误
    }

    int send_count = 0;                             // 发送计数器
    while(running) {                                // 主循环
        if(socket_fd < 0) {                         // 检查连接状态
            printf("Attempting to reconnect...\n"); // 尝试重连
            if(network_connect_to_server() != 0) {  // 重连失败
                sleep(2);                           // 等待2秒后重试
                continue;                           // 继续循环
            }
        }

        // 使用原有的generate_simulated_data函数生成模拟数据
        generate_simulated_data(&send_data);
        // validate_parking_data(&send_data); // 验证数据有效性

        // 序列化数据为JSON格式
        char * json_data = network_serialize_parking_data(&send_data);
        printf("JSON to send (%zu bytes): %s\n", strlen(json_data), json_data);

        // 发送数据到服务器
        ret = send(socket_fd, json_data, strlen(json_data), 0);
        if(ret > 0) { // 发送成功
            printf("[%d] Sent to server: %d bytes\n", send_count, ret);

            // 更新数据到全局存储
            update_parking_data(&send_data);
            // printf("DEBUG: Data updated, triggering UI refresh\n");

            // 使用异步方式更新UI（线程安全）
            parking_data_t * data_copy = malloc(sizeof(parking_data_t));
            if(data_copy) {                                            // 内存分配成功
                memcpy(data_copy, &send_data, sizeof(parking_data_t)); // 复制数据
                lv_async_call(async_ui_update, data_copy);             // 异步调用UI更新
            }

            printf("Data updated and UI refresh triggered manually\n");
        } else { // 发送失败
            printf("Send failed, connection may be lost\n");
            close(socket_fd); // 关闭套接字
            socket_fd = -1;   // 重置套接字描述符
        }

        send_count++; // 增加发送计数
        sleep(5);     // 等待5秒后发送下一条数据
    }

    // 清理资源
    if(socket_fd >= 0) {
        close(socket_fd); // 关闭套接字
    }

    pthread_join(recv_thread, NULL);       // 等待接收线程结束
    printf("TCP Client Thread Stopped\n"); // 线程停止提示
    return NULL;                           // 线程返回值
}

// 启动TCP客户端
void network_start_client(void)
{
    // 创建TCP客户端线程
    if(pthread_create(&tcp_thread, NULL, network_tcp_client_thread, NULL) != 0) {
        printf("Failed to create TCP client thread\n"); // 线程创建失败
        return;                                         // 返回错误
    }
    printf("TCP Client Thread Started\n"); // 线程启动成功提示
}

// 停止TCP客户端
void network_stop_client(void)
{
    running = 0; // 设置运行标志为0，停止所有循环
    if(socket_fd >= 0) {
        close(socket_fd); // 关闭套接字
    }
    pthread_join(tcp_thread, NULL);     // 等待TCP线程结束
    pthread_mutex_destroy(&data_mutex); // 销毁互斥锁
}